#
# Copyright (C) [2024] Xingyun Integrated Circuit, Inc.
#
# GreenCode was a private technology asset of Xingyun Integrated Circuit， Inc （Confidential）
# Author: Shawn.Tan
# Date: 2025.10.28
#
# History: Initial Version 2025.10.28
#
#
from base.Sequence import Sequence
from gpgpu.AssemblyHelperGPGPU import AssemblyHelperGPGPU
from gpgpu.EnvGPGPU import EnvGPGPU
from gpgpu.GenThreadGPGPU import GenThreadGPGPU


# This test verifies that instructions to read read-only system registers
# can be generated.
class MainSequence(Sequence):
    def generate(self, **kargs):
        read_only_reg_names = (
            "marchid",
            "mhartid",
            "mimpid",
            "mvendorid",
            "vl",
            "vlenb",
            "vtype",
        )
        assembly_helper = AssemblyHelperGPGPU(self)
        for _ in range(10):
            gpr_index = self.getRandomGPR(exclude="0")
            read_only_reg_name = self.choice(read_only_reg_names)
            assembly_helper.genReadSystemRegister(gpr_index, read_only_reg_name)

            (sys_reg_val, valid) = self.readRegister(read_only_reg_name)
            self._assertValidRegisterValue(read_only_reg_name, valid)
            gpr_name = "x%d" % gpr_index
            (gpr_val, valid) = self.readRegister(gpr_name)
            self._assertValidRegisterValue(gpr_name, valid)

            gen_mode = self.getPEstate("GenMode")
            no_iss = gen_mode & 0x1
            if (no_iss != 1) and (gpr_val != sys_reg_val):
                self.error(
                    "Register %s was not read correctly. Expected=0x%x, "
                    "Actual=0x%x" % (read_only_reg_name, sys_reg_val, gpr_val)
                )

    # Fail if the valid flag is false.
    #
    #  @param aRegName The name of the register.
    #  @param aValid A flag indicating whether the specified register has a
    #       valid value.
    def _assertValidRegisterValue(self, aRegName, aValid):
        if not aValid:
            self.error("Value for register %s is invalid" % aRegName)


MainSequenceClass = MainSequence
GenThreadClass = GenThreadGPGPU
EnvClass = EnvGPGPU
